package com.dcits.mvc.common.controller;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dcits.business.report.AnalyzeInfoData;
import com.dcits.business.report.AnalyzeUtil;
import com.dcits.business.userconfig.UserSpace;
import com.dcits.constant.ConstantReturnCode;
import com.dcits.mvc.base.BaseController;
import com.dcits.mvc.common.model.ApiDataHistory;
import com.dcits.mvc.common.model.FileInfo;
import com.dcits.mvc.common.service.ApiDataHistoryService;
import com.dcits.mvc.common.service.FileInfoService;
import com.dcits.tool.RmpUtil;
import com.dcits.tool.StringUtils;
import com.jfinal.kit.HttpKit;

public class FileInfoController extends BaseController {
	
	private static final Logger logger = Logger.getLogger(FileInfoController.class);
	private static FileInfoService fileInfoService = new FileInfoService();
	private static ApiDataHistoryService apiDataHistoryService = new ApiDataHistoryService();
	
	public void saveData() {
		UserSpace space = UserSpace.getUserSpace(getPara("userKey"));
		BufferedOutputStream buff = null;
		
		try {
			JSONObject infoData = new JSONObject();
			JSONObject serverList = new JSONObject();
			
			JSONArray serverInfos = new JSONArray();
			JSONObject infoDataM = JSONObject.parseObject(getPara("infoData"));
			infoData.put("infoData", infoDataM);
			infoData.put("serverList", serverList);
						
			for (Map.Entry<String, Object> entry:JSONObject.parseObject(getPara("serverList")).entrySet()) {
				JSONArray typeArr = new JSONArray();
				serverList.put(entry.getKey(), typeArr);
				
				for (Object o:JSONArray.parseArray(entry.getValue().toString())) {
					JSONObject info = JSONObject.parseObject(o.toString());
					JSONObject serverInfo = JSONObject
							.parseObject(JSONObject
									.toJSONString(space
											.getServerInfo(entry.getKey(), info.getInteger("viewId"))));
					if (serverInfo == null) continue; 
					serverInfo.put("startTime", info.get("startTime"));
					serverInfo.put("lastTime", info.get("lastTime"));
					serverInfo.put("count", info.get("count"));
					serverInfos.add(serverInfo);
					typeArr.add(serverInfo);
				}
				
			}
			
			//保存到文件
			String rootPath = getRequest().getSession().getServletContext().getRealPath("");
			String fileName = System.currentTimeMillis() + "_" + getPara("userKey") + ".json";
			String filePath = RmpUtil.DATA_FILE_SAVE_PATH + fileName;
			
			File saveFile = new File(rootPath + "/" + filePath);
			
			buff = new BufferedOutputStream(new FileOutputStream(saveFile));			
			buff.write(infoData.toJSONString().getBytes("UTF-8"));
			buff.flush();
			
			
			FileInfo fileInfo = new FileInfo();
			fileInfo.setConfigId(space.getUserConfig().getId());
			fileInfo.setCreateTime(new Date());
			fileInfo.setFileName(fileName);
			fileInfo.setFilePath(filePath);
			fileInfo.setInfoCount(getParaToInt("infoCount"));
			fileInfo.setServerCount(getParaToInt("serverCount"));
			fileInfo.setServerInfos(serverInfos.toJSONString());
			fileInfo.setMark(getPara("mark"));
			
			String fileSize = "";
			if (saveFile.length() > 1024 * 1024) {
				fileSize = RmpUtil.byteToMB(saveFile.length()) + "MB";
			} else {
				fileSize = RmpUtil.byteToKB(saveFile.length()) + "KB";
			}
			fileInfo.setFileSize(fileSize);
			
			fileInfoService.save(fileInfo);
			
			renderSuccess(filePath, "保存数据成功");
		} catch (Exception e) {
			// TODO: handle exception
			logger.error("保存数据时失败!", e);
			renderError(ConstantReturnCode.SYSTEM_ERROR, "数据保存失败：" + e.getMessage());
			return;
		} finally {
			if (buff != null) {
				try {
					buff.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 可传入查询参数
	 */
	public void list() {
		UserSpace space = UserSpace.getUserSpace(getPara("userKey"));
		String host = getPara("host") == null ? "" : getPara("host");
		String tags = getPara("tags") == null ? "" : getPara("tags");
		//String startTime = getPara("startTime");
		//String lastTime = getPara("lastTime");
		renderSuccess(fileInfoService.listAll(space.getUserConfig().getId(), host, tags), "success");
	}
	
	public void del() {
		FileInfo file = fileInfoService.get(getParaToInt("fileId"));
		if (fileInfoService.del(file.getId())) {
			File f = new File(getRequest().getSession().getServletContext().getRealPath("") + "/" + file.getFilePath());
			if (!(f.exists() && f.delete())) {
				logger.info("文件" + f.getAbsolutePath() + "不存在或者删除失败!");
			}
		}
		renderSuccess(null, "删除成功!");
	}
	
	/**
	 * 导出信息到excel
	 */
	public void exportExcel() {
		JSONArray valueKind = JSONObject.parseArray(getPara("valueKind"));
		JSONObject itemNames = JSONObject.parseObject(getPara("itemName"));
		JSONArray serverList = JSONObject.parseArray(getPara("serverList"));
		JSONObject constant = JSONObject.parseObject(getPara("constant"));
		
		String fileInfo = null;
		try {
			fileInfo = fileInfoService.getFileInfo(getParaToInt("fileId"));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			logger.error("读取文件发生错误!", e);
			renderError(ConstantReturnCode.SYSTEM_ERROR, e.getMessage());
			return;
		}		
		
		JSONObject infoData = JSONObject.parseObject(fileInfo);		
		
		Map<String, List<AnalyzeInfoData>> analyzeInfoDatas = new HashMap<String, List<AnalyzeInfoData>>();
		String serverType;
		for (Object server:serverList) {
			JSONObject serverObj = JSONObject.parseObject(server.toString());
			
			serverType = serverObj.getString("serverType");
			
			AnalyzeInfoData analyzeInfoData = new AnalyzeInfoData(serverObj.getInteger("viewId"),
					serverObj.getString("host"), serverType, constant.getJSONObject(serverType));
			analyzeInfoData.analyzeInfo(itemNames.getJSONArray(serverType), infoData, null, null);
			List<AnalyzeInfoData> typeAnalyzeInfoDatas = analyzeInfoDatas.get(serverType);
			if (typeAnalyzeInfoDatas == null) {
				typeAnalyzeInfoDatas = new ArrayList<AnalyzeInfoData>();
				analyzeInfoDatas.put(serverType, typeAnalyzeInfoDatas);
			}
			typeAnalyzeInfoDatas.add(analyzeInfoData);
		}
		
		try {
			String path = RmpUtil.ExportInfoData(analyzeInfoDatas, valueKind,  getRequest().getSession().getServletContext().getRealPath(""));
			renderSuccess(path, "导出excel成功!");
		} catch (Exception e) {
			// TODO: handle exception
			logger.error("保存到excel出错" + e.getMessage() + "!", e);
			renderError(ConstantReturnCode.SYSTEM_ERROR, "保存到excel出错" + e.getMessage() + "!");
		}
		
	}
	
	public void getInfoData() {
		String fileInfo = null;
		try {
			fileInfo = fileInfoService.getFileInfo(getParaToInt("fileId"));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			logger.error("读取文件发生错误!", e);
			renderError(ConstantReturnCode.SYSTEM_ERROR, e.getMessage());
			return;
		}
		
		renderSuccess(JSONObject.parse(fileInfo), "读取信息成功!");		
	}
	
	/**
	 * 非功能性测试资源数据分析
	 */
/*	public void analyzeApiData() {
		String fileInfo = null;
		try {
			fileInfo = fileInfoService.getFileInfo(getParaToInt("fileId"));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			logger.error("读取文件发生错误!", e);
			renderError(ConstantReturnCode.SYSTEM_ERROR, e.getMessage());
			return;
		}
		JSONObject serverList = JSONObject.parseObject(getPara("serverList"));
		JSONObject apiData = JSONObject.parseObject(getPara("apiData"));
		JSONObject itemNames = JSONObject.parseObject(getPara("itemNames"));
		
		//分析全部数据
		Map<String, List<AnalyzeInfoData>> analyzeInfoDatas = AnalyzeUtil.analyzeAllFileInfo(JSONObject.parseObject(fileInfo),
				itemNames, null);
		
		//创建指定的json对象
		JSONObject object = AnalyzeUtil.createNonFunctionalTestResourceObject(analyzeInfoDatas, apiData, serverList);
		renderSuccess(object, null);	
	}*/
	
	/**
	 * 解析文件信息，返回给前台指定格式的应用资源列表
	 */
	public void analyzeApiData() {
		String fileInfo = null;
		try {
			fileInfo = fileInfoService.getFileInfo(getParaToInt("fileId"));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			logger.error("读取文件发生错误!", e);
			renderError(ConstantReturnCode.SYSTEM_ERROR, e.getMessage());
			return;
		}
		JSONObject apiData = JSONObject.parseObject(getPara("apiData"));
		JSONObject itemNames = JSONObject.parseObject(getPara("itemNames"));
		
		//分析全部数据
		Map<String, List<AnalyzeInfoData>> analyzeInfoDatas = AnalyzeUtil.analyzeAllFileInfo(JSONObject.parseObject(fileInfo),
				itemNames, null, getPara("testTime"));
		//创建绑定数据的资源数据列表
		JSONObject serverList = AnalyzeUtil.createBindedDataServerInfoObject(analyzeInfoDatas, apiData, JSONObject.parseObject(fileInfo).getJSONObject("serverList"));
		
		renderSuccess(setData("serverList", JSONObject.toJSONString(serverList)), "分析成功!");
	}
	
	/**
	 * 发送分析数据到对接地址
	 */
	public void sendApiData() {
		UserSpace space = UserSpace.getUserSpace(getPara("userKey"));
		String apiUrl = space.getUserConfig().parseUserSetting().getOther().get("apiUrl").toString();
		
		if (StringUtils.isEmpty(apiUrl)) {
			renderError(ConstantReturnCode.VALIDATE_FAIL, "与需求管理平台的数据同步地址未设定，请至配置选项模块查看并设置!");
			return;
		}
		
		JSONObject sendData = new JSONObject();
		sendData.put("data", JSONObject.parseObject(getPara("apiData")));
		//sendData.put("mark", getPara("apiMark"));
		sendData.put("id", getPara("apiIdentity"));
		Map<String, String> headers = new HashMap<String, String>();
		headers.put("Content-type", "application/json");
		
		String returnInfo = HttpKit.post(apiUrl , sendData.toJSONString(), headers);
		logger.info("发送内容：" + sendData.toJSONString());
		renderSuccess(null, "已发送至：" + apiUrl + "<br>返回内容:<br><span style=\"color:#FF5722;\">" + StringEscapeUtils.escapeHtml4(returnInfo) 
				+ "</span>");
	}
	
	public void delApiData() {
		apiDataHistoryService.del(getParaToInt("id"));
		renderSuccess(null, "删除成功!");
	}
	
	/**
	 * 保存非功能数据库到数据库<br>同时生成文excel文件
	 */
	public void saveApiData() {
		ApiDataHistory data = getModel(ApiDataHistory.class, "", true);
		if (StringUtils.isEmpty(data.getApiIdentity())) {
			renderError(ConstantReturnCode.VALIDATE_FAIL, "需求标识不完整正确");
			return;
		}
		if (apiDataHistoryService.findByIdentity(data.getApiIdentity()) != null) {
			renderError(ConstantReturnCode.VALIDATE_FAIL, "该需求标识对应的数据已存在,请更换或者先手动删除历史记录!");
			return;
		}
		
		try {
			apiDataHistoryService.save(data.setSaveTime(new Date())
					.setFilePath(""));
		} catch (Exception e) {
			// TODO: handle exception
			logger.error("保存数据失败!", e);
			renderError(ConstantReturnCode.SYSTEM_ERROR, "保存数据失败:" + e.getMessage());
			return;
		}
		renderSuccess(null, "保存成功!");
	}
	
	/**
	 * 获取历史发送的资源对接数据
	 */
	public void listApiDataHistory() {
		renderSuccess(apiDataHistoryService.listAll(), "success");
	}
	
	/**
	 * 获取文件信息并返回最大最小的监控时间
	 */
	public void validateFileInfo() {
		Integer fileId = getParaToInt("fileId");
		JSONObject fileInfo = null;
		try {
			String str = fileInfoService.getFileInfo(fileId);
			fileInfo = JSONObject.parseObject(str);
		} catch (Exception e) {
			// TODO: handle exception
			logger.error("读取文件发生错误!", e);
			renderError(ConstantReturnCode.VALIDATE_FAIL, e.getMessage());
			return;
		}
		JSONObject rangeTime = AnalyzeUtil.getMonitoringRangeTime(fileInfo);
		if (rangeTime == null) {
			renderError(ConstantReturnCode.VALIDATE_FAIL, "记录数据不足或者有误,请检查");
			return;
		}
		
		renderSuccess(rangeTime, "获取成功");
	}
	
	/**
	 * 创建最终要发送的json数据
	 */
	public void createFinalJson() {
		renderSuccess(AnalyzeUtil.createNonFunctionalTestResourceObject(JSONObject.parseObject(getPara("serverList"))), null);	
	}
	
}
